import { ChangeDetectionStrategy, Component } from '@angular/core';
import { AgRendererComponent } from '@ag-grid-community/angular';
import { ICellRendererParams } from '@ag-grid-community/core';
import { deepClone, getO, getValueUsingField } from '../../../utils/utils';
import { ExpressionService } from '@core/services/expression/ExpressionService';
import { Events } from '@core/services/events/Events';
import { ApesContextMenuService } from '@shared/ag-grid-ext/context-menu';
import { ApesModalService } from '@shared/apes/modal';

@Component({
  selector: 'apes-render-default',
  template: `
    <div class="render-default" [ngStyle]="checkDefaultStyle()">

      <ng-container *ngIf="showPrefix && showGroup(this.prefixOption) && !hideBtnBar">
        <div class="render-default-showPrefix">
          <ng-container *ngTemplateOutlet="commonTemplate;context:{option: prefixOption}"></ng-container>
        </div>
      </ng-container>

      <ng-container *ngIf="!showTooltip && !showPopover">
        <div class="render-default-showValue"
             [ngClass]="checkValueStyle()">
          <span>
            {{getName(params.value)}}
          </span>

        </div>
      </ng-container>

      <ng-container *ngIf="showTooltip">
        <div class="render-default-showValue"
             [ngClass]="checkValueStyle()"
             [apes-tooltip]="getName(params.value)">
          {{getName(params.value)}}
        </div>
      </ng-container>

      <ng-container *ngIf="showPopover">
        <div class="render-default-showValue"
             apes-popover
             [apesPopoverContent]="popoverTemplate"
             apesPopoverPlacement="topLeft"
             [apesVisible]="popoverVisible"
             (click)="showPopoverVisible('click')"
             (mouseenter)="showPopoverVisible('mouseenter')"
             (mouseleave)="showPopoverVisible('mouseleave')"
             apesPopoverTrigger="null">
          {{getName(params.value)}}
        </div>
        <ng-template #popoverTemplate>
          <div class="apes-cell-inputPopover">
            {{getName(params.value)}}
          </div>
        </ng-template>
      </ng-container>

      <ng-container *ngIf="showSuffix && showGroup(this.suffixOption) && !hideBtnBar">
        <div class="render-default-showSuffix">
          <ng-container *ngTemplateOutlet="commonTemplate;context:{option: suffixOption}"></ng-container>
        </div>
      </ng-container>

    </div>

    <ng-template #commonTemplate let-option="option">

      <ng-container *ngIf="option['type'] == 'string'">

        <ng-container *ngIf="!option['showFixTooltip']">
          <div>{{option['textFormatter']}}</div>
        </ng-container>

        <ng-container *ngIf="option['showFixTooltip']">
          <div [apes-tooltip]="getFormatter(option['textFormatter'],option['tooltipFormatter'])">
            {{option['textFormatter']}}
          </div>
        </ng-container>

      </ng-container>

      <ng-container *ngIf="option['type'] == 'icon'">

        <ng-container *ngIf="!option['showTooltip']">
          <i apes-icon
             class="render-default-icon"
             [ngClass]="{
             'icon-pointer': checkBtnClass(option['action']),
             'icon-UD-change': option['iconClass'] == 'UDChange'
             }"
             [apesType]="showIconType(option['textFormatter'])"
             (click)="clickBtn(option)"></i>
        </ng-container>

        <ng-container *ngIf="option['showTooltip']">
          <i apes-icon
             class="render-default-icon"
             [ngClass]="{
             'icon-pointer': checkBtnClass(option['action']),
             'icon-UD-change': option['iconClass'] == 'UDChange'
             }"
             [apesType]="showIconType(option['textFormatter'])"
             apes-tooltip
             [apesTooltipTitle]="iconTemplate"
             (click)="clickBtn(option)"></i>
        </ng-container>
        <ng-template #iconTemplate>
          <div [innerHTML]="getFormatter(option['textFormatter'],option['tooltipFormatter'])"></div>
        </ng-template>
      </ng-container>

      <ng-container *ngIf="option['type'] == 'tag'">

        <ng-container *ngFor="let tag of items">

          <ng-container *ngIf="showTagFormatter(tag) && tag.hasOwnProperty('tooltipFormatter')">
            <apes-tag apes-tooltip
                      [apes-tooltip]="getFormatter(option['textFormatter'],tag['tooltipFormatter'])"
                      [apesColor]="tag.color? tag.color : 'cyan'">{{tag.name}}</apes-tag>

          </ng-container>

          <ng-container *ngIf="showTagFormatter(tag) && !tag.hasOwnProperty('tooltipFormatter')">
            <apes-tag [apesColor]="tag.color? tag.color : 'cyan'">{{tag.name}}</apes-tag>
          </ng-container>

        </ng-container>

      </ng-container>

    </ng-template>
  `,
  styles: [
      `
      .render-default {
        display: flex;
        overflow: hidden;
        line-height: 1;
      }

      .render-default-showValue {
        display: flex;
        align-items: center;
        /*white-space: pre-wrap;*/
      }

      .render-default-nowrap {
        overflow: hidden;
        white-space: nowrap;
        text-overflow: 'ellipsis';
      }

      .render-default-preWrap {
        white-space: pre-wrap;
      }


      .render-default-showPrefix, .render-default-showSuffix {
        height: 28px;
        padding: 4px 0;
        display: flex;
        align-items: center;
      }

      .render-default-icon {
        font-size: 14px;
        display: block;
        margin: 0 4px;
      }

      .icon-pointer {
        cursor: pointer;
      }

      .icon-UD-change {
        /*border: 1px solid;*/
        border-radius: 50%;
        padding: 1px;
        font-size: 10px;
      }

      .icon-UD-change.anticon-arrow-up {
        background: #fadddf;
        color: #e55b67;
      }

      .icon-UD-change.anticon-arrow-down {
        background: #bcebdc;
        color: #4ec39d;
      }
    `,
  ],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ApesRenderDefaultComponent implements AgRendererComponent {
  value: any;
  params: ICellRendererParams;
  valueFormatter: any;
  showTooltip: boolean = false;
  showPopover: boolean = false;
  ctx: any = {};
  data: any = {};
  placeholder: any = '';
  rowIndex: any;
  inputValue: any = '';

  callbackBody: any;
  showPrefix: boolean = false;
  prefixOption: any = {};
  showSuffix: boolean = false;
  suffixOption: any = {};
  defaultStyle: any;
  valueStyle: any;

  items: any[] = [];
  hideBtnBar: boolean = false;


  popoverVisible: boolean = false;

  constructor(
    private  expressionService: ExpressionService,
    private contextService: ApesContextMenuService,
    private modalService: ApesModalService,
    private event: Events) {
  }

  refresh(params: any): boolean {
    return false;
  }

  agInit(params: ICellRendererParams): void {
    this.params = params;
    this.rowIndex = deepClone(this.params.rowIndex);
    this.ctx = params.context;
    let colDef;
    if (params.hasOwnProperty('colDef')) {
      this.data = this.params.data;
      colDef = params.colDef;
    } else {
      this.data = this.params.node.data;
      colDef = params.column['colDef'];
    }
    this.initData(colDef);
    this.inputValue = this.getName(params.value);

    if (this.data && this.data.hasOwnProperty('hideBtnBar')) {
      this.hideBtnBar = true;
    }
  }

  initData(colDef) {
    if (colDef.hasOwnProperty('valueFormatter')) {
      this.valueFormatter = deepClone(colDef['valueFormatter']);
    }
    if (colDef.hasOwnProperty('showTooltip')) {
      this.showTooltip = true;
    }
    if (colDef.hasOwnProperty('showPopover')) {
      this.showPopover = true;
    }
    if (colDef.hasOwnProperty('placeholder')) {
      this.placeholder = colDef.placeholder;
    }
    if (colDef.hasOwnProperty('callback')) {
      this.callbackBody = colDef.callback;
    }
    if (colDef.hasOwnProperty('showPrefix')) {
      this.prefixOption = this.initOption(colDef, 'showPrefix');
      // this.showPrefix = this.showGroup(this.prefixOption);
      this.showPrefix = true;
    }
    if (colDef.hasOwnProperty('showSuffix')) {
      this.suffixOption = this.initOption(colDef, 'showSuffix');
      // this.showSuffix = this.showGroup(this.suffixOption);
      this.showSuffix = true;
    }
    if (colDef.hasOwnProperty('defaultStyle')) {
      this.defaultStyle = colDef.defaultStyle;
    }
    if (colDef.hasOwnProperty('valueStyle')) {
      this.valueStyle = colDef.valueStyle;
    }
    if (colDef.hasOwnProperty('items')) {
      this.items = getO(colDef.items);
    }


    if (colDef.hasOwnProperty('options')) {
      let options = getO(colDef.options);
      options.forEach((option) => {
        switch (option['group']) {
          case 'prefix':
            this.prefixOption = this.initOption(option, 'showPrefix');
            // this.showPrefix = this.showGroup(this.prefixOption);
            this.showPrefix = true;
            break;
          case 'suffix':
            this.suffixOption = this.initOption(option, 'showSuffix');
            // this.showSuffix = this.showGroup(this.suffixOption);
            this.showSuffix = true;
            break;
        }
      });
    }
  }

  initOption(params, fix) {
    return {
      group: params['group'] ? params['group'] : fix == 'showPrefix' ? 'prefix' : 'suffix',
      type: params['showType'] ? params['showType'] : 'string',
      textFormatter: params[fix] ? params[fix] : '',
      showGroupFormatter: params['showGroupFormatter'],
      showTooltip: !!params['showFixTooltip'],
      tooltipFormatter: params['showFixTooltip'] ? params['showFixTooltip'] : '',
      action: params['action'] ? params['action'] : 'text',
      callback: params['callback'] ? params['callback'] : false,
      api: params['api'],
      config: params['config'],
      iconClass: params['iconClass'] ? params['iconClass'] : '',
    };
  }

  checkDefaultStyle() {
    let style = 'space-between';
    if (this.defaultStyle) {
      style = this.defaultStyle;
    }
    return { 'justifyContent': style };
  }

  checkValueStyle() {
    switch (this.valueStyle) {
      case 'nowrap':
        return 'render-default-nowrap';
      case 'preWrap':
        return 'render-default-preWrap';
    }
  }

  checkBtnClass(action) {
    let show = false;
    switch (action) {
      case 'button':
        show = true;
        break;
      case 'link':
        show = true;
        break;
      case 'pointer':
        show = true;
        break;
    }
    return show;
  }

  showIconType(formatter) {
    let expression = this.expressionService.eval(formatter, {
      context: this.ctx,
      model: this.ctx['model'],
      data: this.data,
    });

    return expression ? expression : formatter;
  }

  showGroup(params) {
    let expression = params.showGroupFormatter || 'true';
    return this.expressionService.eval(expression, {
      context: this.ctx,
      model: this.ctx['model'],
      data: this.data,
    });
  }

  showPopoverVisible(type) {
    switch (type) {
      case 'mouseenter':
        this.popoverVisible = true;
        break;
      case 'mouseleave':
        this.popoverVisible = false;
        break;
      case 'click':
        if (this.popoverVisible) {
          this.popoverVisible = false;
        }
        break;
    }
  }

  clickBtn(btn) {
    switch (btn.action) {
      case 'button':
        this.openButton(btn);
        break;
      case 'link':
        this.openLink(btn);
        break;
    }
  }

  openButton(btn) {
    let node = { ...btn, rowIndex: this.rowIndex, event: this.event };

    this.expressionService.evaluate(this.callbackBody, {
      context: this.ctx,
      form: this.ctx['form'],
      model: this.ctx['model'],
      data: this.data,
      node: node,
    }, true);
  }

  openLink(btn) {
    let data = this.data;
    let config = deepClone(btn.config);
    let callbackBody = this.callbackBody;

    let api = this.expressionService.evaluate(btn.api, {
      context: this.ctx,
      model: this.ctx['model'],
      data: this.data,
    });

    let configApi = this.expressionService.evaluate(config.api, {
      context: this.ctx,
      model: this.ctx['model'],
      data: this.data,
    });

    if (api == null) {
      api = btn.api;
    }

    if (configApi != null) {
      config.api = configApi;
    }

    let resultData = {};
    if (callbackBody) {
      let node = { ...btn };
      resultData = this.expressionService.evaluate(callbackBody, {
        context: this.ctx,
        model: this.ctx['model'],
        data: this.data,
        node: node,
      }, true);
    } else {
      resultData = data;
    }
    this.modalService.closeAll(); // 用于解决弹框里面的跳转关闭弹框
    this.contextService.openContextLink(resultData, api, config);
  }

  getFormatter(value, formatter) {
    return this.formatter(value, formatter || 'value');
  }

  getName(value) {
    this.value = this.formatter(value, this.valueFormatter || 'value');
    return this.value;
  }

  showTagFormatter(tag): string {
    let expression = tag.valueFormatter || false;
    return this.expressionService.evaluate(expression, {
      context: this.ctx,
      model: this.ctx['model'],
      data: this.data,
    });
  }

  formatter(value: any, expression: string) {
    return this.expressionService.evaluate(expression, {
      context: this.ctx,
      model: this.ctx['model'],
      data: this.data,
      value: value,
    });
  }
}
